<?php

// +----------------------------------------------------------------------
// | 中犇单商户
// +----------------------------------------------------------------------
// | Copyright (c) 2019-2021 中犇科技 All rights reserved.
// +----------------------------------------------------------------------

namespace app\api\controller\v1;

use app\api\controller\Base;
use app\goods\model\Category;
use app\goods\model\Brand as BrandModel;
use app\order\model\Freight;
use app\goods\model\Goods as GoodsModel;
use app\goods\model\GoodsCommentCollect;
use app\user\model\Task as TaskModel;
use app\goods\model\GoodsSku;
use app\user\model\Address as AddressModel;
use app\user\model\User;
use service\ApiReturn;
use think\Db;
use service\Tree;
use app\operation\model\Coupon as CouponModel;
use app\goods\model\Type;
use app\goods\model\GoodsTypeSpecItem;
use app\goods\model\GoodsComment;
use app\goods\model\GoodsQuestion;
use app\user\model\Pickup as UserPickupModel;

/**
 * 商品接口
 * @package app\api\controller\v1
 */
class Goods extends Base
{

    /**
     * 获取商品分类
     * @param array $data
     * @param array $user
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     * @created 2019/10/22 8:58
     */
    public function get_category_list($data = [], $user = [])
    {

        //查询所有分类
        $where['cate.is_show'] = 1;
        $where['cate.status'] = 1;
        $categoryList = Category::alias('cate')->join('upload u', 'cate.thumb=u.id', 'left')
            ->where($where)->order('cate.sort asc,cate.id desc')
            ->column("cate.id,cate.pid,cate.name,cate.thumb");
        foreach ($categoryList as &$value) {
            $value['thumb'] = get_file_url($value['thumb']);
        }
        if ($categoryList) {
            //格式化输出
            $categoryList = Tree::toLayer($categoryList, $data['pid'], $data['max_level']);
            foreach ($categoryList as &$value) {
                if ($value['pid'] == 0) {
                    $value['bind_list'] = BrandModel::alias('a')->join('upload u', 'a.logo=u.id', 'left')->where(['cid' => $value['id'], 'is_hot' => 1])->field('a.id,a.logo,a.name,u.path')->select();
                }
            }
            $this->filterData($categoryList);
            return ApiReturn::r(1, $categoryList, lang('请求成功'));
        }
        return ApiReturn::r(1, [], lang('暂无数据'));
    }

    //商品分类接口
    public function get_goods_brand($data = [], $user = [])
    {
        $where = [];
        if (isset($data['cid'])) {
            if ($data['cid'] != 0) {
                $category_ids = $this->getAllCodeTypeByCid($data['cid']);   //获取商品分类ID
                $where[] = ['cid', 'IN', $category_ids];
            } else {
                $where[] = ['cid', '=', $data['cid']];
            }
        }

        $lists = BrandModel::where(['status' => 1])->where($where)->order('sort DESC')->select();
        foreach ($lists as &$value) {
            $value['logo'] = get_file_url($value['logo']);
        }
        return ApiReturn::r(1, $lists, lang('请求成功'));
    }

    //推荐分类接口
    public function get_category_hot($data = [], $user = [])
    {
        $lists = Category::where(['status' => 1, 'is_hot' => 1])->order('sort DESC')->select();
        foreach ($lists as &$value) {
            $value['thumb'] = get_file_url($value['thumb']);
        }
        return ApiReturn::r(1, $lists, lang('请求成功'));
    }

    protected function filterData(&$data)
    {
        if ($data) {
            $data = array_values($data);
            foreach ($data as &$item) {
                if (isset($item['child'])) {
                    $item['child'] = $this->filterData($item['child']);
                }
            }
            return $data;
        }
    }

    //输入商品分类ID返回分类下级的所有ID(包括自己)
    public static function getAllCodeTypeByCid($cid)
    {
        return Category::getChildsId($cid);       
    }

    /**
     * 获取指定栏目的商品列表
     * @author 晓风<215628355@qq.com>
     * @created 2021年11月5日09:53:26
     */
    public function get_goods_list($data)
    {
        $where = [];
        if ($data['type'] == 1 && $data['cid']) {
            $where[] = ['g.brand_id', "=", $data['cid']];
            $data['cid'] = null;
        }
        // 商品分类
        if ($data['cid']) {
            $category_ids = self::getAllCodeTypeByCid($data['cid']);
            $where[] = ['g.cid', "in", $category_ids];
        } // 商品分类单独查询
        else if ($data['goods_cid']) {
            $category_ids = self::getAllCodeTypeByCid($data['goods_cid']);
            $where[] = ['g.cid', "in", $category_ids];
        }
        // 商品ID
        if ($data['id']) {
            $where[] = ['g.id', "=", $data['id']];
        }
        // SKU检索商品
        if ($data['sku_id']) {
            $skuWhere = GoodsModel::getFinInsetAll($data['sku_id'], "REPLACE(`key`,'_',',')");
            if ($skuWhere) {
                $where[] = ["g.id", "in", function ($query) use ($skuWhere) {
                    $query->name("goods_sku")->where($skuWhere)->field("goods_id");
                }];
            }
        }
        // 搜索关键字
        if ($data['keyword']) {
            $where[] = GoodsModel::getKeywordWhereMap($data['keyword'], 'g.name|g.keywords');
        }
        // 服务标签ID
        if ($data['service_lable_id']) {
            $labelWhere = GoodsModel::getFinInsetAll($data['service_lable_id'], 'g.goods_label_service');
            if ($labelWhere) {
                $where[] = $labelWhere;
            }
        }
        // 品牌ID
        if ($data['brand_id']) {
            $arr = array_filter(array_unique(explode(',', $data['brand_id'])));
            if ($arr) {
                $where[] = ['g.brand_id', "in", $arr];
            }
        }
        // 商品价格区间搜索
        if (!empty($data['min_price']) && $data['min_price'] > 0) {
            $where[] = ['g.shop_price', ">", $data['min_price']];
        }
        if (!empty($data['max_price']) && $data['max_price'] > 0) {
            $where[] = ['g.shop_price', "<=", $data['max_price']];
        }

        // 排序处理
        $order = ['id' => 'desc'];
        if ($data['order']) {
            switch ($data['sort']) {
                case 1:
                    $order = ['sort' => 'asc'];
                    break;
                case 2:
                    $order = ['g.sales_sum' => $data['order']];
                    break;
                case 3:
                    $order = ['g.shop_price' => $data['order']];
                    break;
                case 4:
                    $order = ['g.member_price' => $data['order']];
                    break;
                default:
                    break;
                // $order = "";
            }
        }

        // 类型查询
        if ($data['goods_type']) {
            switch ($data['goods_type']) {
                case 1:
                    $where[] = ['g.is_sale', "eq", 1];
                    break;
                case 2:
                    $where[] = ['g.is_recommend', "eq", 1];
                    $where[] = ['g.is_sale', "eq", 1];
                    break;
                case 3:
                    $where[] = ['g.is_boutique', "eq", 1];
                    $where[] = ['g.is_sale', "eq", 1];
                    break;
                case 4:
                    $where[] = ['g.is_new', "eq", 1];
                    $where[] = ['g.is_sale', "eq", 1];
                    break;
                case 5:
                    $where[] = ['g.is_hot', "eq", 1];
                    $where[] = ['g.is_sale', "eq", 1];
                    break;
                default:
                    $where[] = ['g.is_sale', "eq", 1];
                    break;
            }
        }


        $page = $data['page'] ?? 1;
        $size = $data['list_rows'] ?? 10;
        // 查询商品数据
        $goods_list = GoodsModel::goods_list($where, $order, $size, $page);
        $total = GoodsModel::alias("g")
            ->where($where)
            ->where([['g.is_delete', '=', 0], ['g.is_sale', '=', 1], ['g.status', '=', 1]])
            ->count();

        return ApiReturn::r(1, ['data' => $goods_list, 'total' => $total], lang('请求成功'));
    }

    /**
     * 获取商品详情
     * @param array $data
     * @param array $user
     * @author 晓风<215628355@qq.com>
     * @created 2019/11/28 8:19
     */
    public function get_goods_detail($data = [], $user = [])
    {

        $data['user_id'] = !empty($data['user_id']) ? $data['user_id'] : ($user['id'] ?? 0);
        $goodsId = $data['goods_id'];

        //缓存不存在或者强制更新，则重新查询商品信息
        $where[] = ['g.id', 'eq', $goodsId];
        $where[] = ['g.is_sale', 'eq', 1];
        $where[] = ['g.is_delete', 'eq', 0];
        $GoodsModel = new GoodsModel();
        $goods = $GoodsModel->goods_detail($where);
        if (!$goods) {
            return ApiReturn::r(1, [], lang('暂无数据'));
        }      
        $goods['coupon_list'] = CouponModel::getGoodsInfoNew($goods["id"], $goods["cid"] ,$data['user_id']);
        $goods['activity_info'] = [
            'activity_type' => 0,
        ];
        $goods['user_level'] = 0;

        //是否收藏
        $collect = 0;
        if ($data['user_id']) {
            $collect = Db::name('user_collection')->where(['type' => 1, 'collect_id' => $goodsId, 'user_id' => $data['user_id']])->count();
        }
        $goods['is_collect'] = $collect ? 1 : 0;

        $comment = Db::name('goods_comment')->alias('c')
            ->join('user u', 'c.user_id = u.id')
            ->join('order_goods_list og', 'c.order_sn = og.order_sn and c.goods_id = og.goods_id and c.sku_id = og.sku_id', "left")
            ->field('c.id,c.type,c.thumb,c.video,c.create_time,c.content,c.star,u.head_img,u.user_nickname,c.sku_id,og.sku_name as key_name')
            ->where(['c.goods_id' => $data['goods_id'], 'c.status' => 1])
            ->order('c.create_time desc')
            ->limit(3)
            ->select();
        foreach ($comment as &$item) {
            if ($item['type'] == 1) {
                $item['user_nickname'] = lang('匿名用户');
                $item['head_img'] = config('web_site_domain') . '/static/admin/images/user_none.png';
            } else {
                $item['user_nickname'] = str2sub($item['user_nickname'], 1, '***');
                $item['head_img'] = get_file_url($item['head_img']);
            }
            if (strpos($item['head_img'], 'images/none.png') !== false) {
                $item['head_img'] = config('web_site_domain') . '/static/admin/images/user_none.png';
            }
            $item['thumb'] = get_files_url($item['thumb']);
            $item['video'] = get_files_url($item['video']);
            $item['create_time'] = date('Y-m-d', $item['create_time']);
            //是否点赞
            $item['is_likes'] = GoodsCommentCollect::isCollection($data['user_id'], $item['id']) ?? 0;
        }
        $goods['comment'] = $comment;
        $goods['comment_total'] = Db::name('goods_comment')->where(['goods_id' => $data['goods_id'], 'status' => 1])->count();
        //计算好评率 zhougs
        $commentWhere[] = ["goods_id", "=", $data['goods_id']];
        $commentWhere[] = ["status", "=", 1];
        $commentWhere[] = ["star", "gt", 3];
        $niceCommentNumber = Db::name('goods_comment')->where($commentWhere)->count('id');
        $goods['praise_rate'] = 0;
        if ($goods['comment_total'] > 0) {
            $goods['praise_rate'] = round(($niceCommentNumber / $goods['comment_total']) * 100);
        }

        $freight = Freight::where("id", $goods['freight_template_id'])->field("name,freight_explain")->find();
        $goods['freight_explain'] = $freight['freight_explain'];
        $goods['freight_name'] = $freight['name'];
        if ((int)$goods['freight_price'] == 0) {
            $goods['freight_price'] = 0;
        }
        $goods['sale_top_name'] = ""; //排行榜暂时屏蔽

        $goods['question_total'] = GoodsQuestion::where("goods_id", $data['goods_id'])->where(['status' => 1])->count();
        //商品问答
        $goods['question_list'] = GoodsQuestion::alias("q")->join("goods_answer a", "q.id=a.question_id and a.status=1", "left")
            ->field("q.id,q.goods_id,q.goods_name,q.goods_thumb,q.content question_content,a.content answer_content,count(a.user_id) answer_number")
            ->where("q.goods_id", $data['goods_id'])
            ->where(['q.status' => 1])
            ->group("q.id")
            ->order("q.create_time DESC")
            ->limit(3)
            ->select()
            ->each(function ($item) {
                $item['goods_thumb'] = get_file_url($item['goods_thumb']);
                return $item;
            });

        //记录浏览历史
        if ($data['user_id']) {
             \app\user\model\Collection::addTodayHistory(3, $data['user_id'], $goods['id'],$goods['name']);     
            TaskModel::doTask($data['user_id'], 'browseGoods');
        }
        //商品类型-暂时屏蔽
        $goods['goods_type'] = 0; //默认普通商品
        //聊天价格显示--暂时 屏蔽
        $goods['chat_price'] = $goods["shop_price"];
        $goods["body"] = GoodsModel::stripTags($goods["body"]);
        GoodsModel::where('id', $goodsId)->setInc('click');
        //格式化输出
        return ApiReturn::r(1, $goods, lang('请求成功'));
    }

    /**
     * 获取商品评论列表
     * @param array $data
     * @author jxy [ 41578218@qq.com ]
     * @created 2019/11/28 15:19
     */
    public function commentList($data = [])
    {
        if ($data['type'] == 1) {
            $order = 'c.create_time DESC';
        } else if ($data['type'] == 2) {
            $order = 'c.star DESC,c.create_time DESC';
        } else {
            $order = 'c.create_time DESC';
        }
        $map = [];
        $having = "";
        if ($data['star_type'] == "good") {
            $map[] = ["c.star", "gt", 3];
        } elseif ($data['star_type'] == "middle") {
            $map[] = ["c.star", "=", 3];
        } elseif ($data['star_type'] == 'bad') {
            $map[] = ["c.star", "lt", 3];
        } elseif ($data['star_type'] == 'is_likes') {
            $having = "likes_num > 0";
        } elseif ($data['star_type'] == 'pictures') {
            $map[] = ['thumb', '<>', ''];
        } else {
            $map = [];
        }
        if (isset($data['filter_type']) && $data['filter_type']) {
            if ($data['filter_type'] == 'thumb') {
                $map[] = ['thumb', '<>', ''];
            } elseif ($data['filter_type'] == 'video') {
                $map[] = ['video', '>', 0];
            } else {
                $map[] = ['content', '<>', ''];
            }
        }
        $from = Db::name('goods_comment')->alias('c')
            ->leftJoin('user u', 'c.user_id = u.id')
            ->leftJoin("goods_comment_collect gcc", "c.id = gcc.collect_id")
            ->leftJoin('order_goods_list og', 'c.order_sn = og.order_sn and c.goods_id = og.goods_id and c.sku_id = og.sku_id')
            ->field('c.id,c.type,c.thumb,c.video,c.create_time,c.content,c.star,u.head_img,u.user_nickname,c.sku_id,c.pid,count(gcc.id) as likes_num,og.sku_name as key_name')
            ->where(['c.goods_id' => $data['goods_id'], 'c.status' => 1])
            ->where($map)
            ->group("c.id")
            ->order($order);
        if ($having) {
            $from = $from->having("count(gcc.id) > 0");
        }
        $list = $from->paginate();
        $comment = $list->items();
        $total = $list->total();

        //halt(Db::name('goods_comment')->getLastSql());
        foreach ($comment as $key => &$item) {
            if ($item['type'] == 1) {
                $item['user_nickname'] = lang('匿名用户');
                $item['head_img'] = config('web_site_domain') . '/static/admin/images/user_none.png';
            } else {
                $item['user_nickname'] = str2sub($item['user_nickname'], 1, '***');
                $item['head_img'] = get_file_url($item['head_img']);
            }
            if (strpos($item['head_img'], 'images/none.png') !== false) {
                $item['head_img'] = config('web_site_domain') . '/static/admin/images/user_none.png';
            }
            $item['thumb'] = get_files_url($item['thumb']);
            $item['video'] = get_files_url($item['video']);
            $item['create_time'] = date('Y-m-d', $item['create_time']);
            $comment[$key]['is_likes'] = GoodsCommentCollect::isCollection($data['user_id'], $item['id']) ?? 0;
        }
        // zenghu ADD 返回评论列表tab栏 2020年12月25日14:05:43
        $tabList = [
            [
                'type_title' => lang('全部'),
                'type_name' => 'all',
                'type_count' => GoodsComment::getGoodsCommentCount(['goods_id' => $data['goods_id'], 'status' => 1]),
            ],
            [
                'type_title' => lang('好评'),
                'type_name' => 'good',
                'type_count' => GoodsComment::getGoodsCommentCount("goods_id = {$data['goods_id']} AND status = 1 AND star > 3"),
            ],
            [
                'type_title' => lang('中评'),
                'type_name' => 'middle',
                'type_count' => GoodsComment::getGoodsCommentCount("goods_id = {$data['goods_id']} AND status = 1 AND star = 3"),
            ],
            [
                'type_title' => lang('差评'),
                'type_name' => 'bad',
                'type_count' => GoodsComment::getGoodsCommentCount("goods_id = {$data['goods_id']} AND status = 1 AND star < 3"),
            ],
            [
                'type_title' => lang('有图'),
                'type_name' => 'pictures',
                'type_count' => GoodsComment::getGoodsCommentCount("goods_id = {$data['goods_id']} AND status = 1 AND thumb != ''"),
            ],
            //[
            //    'type_title' => lang('点赞'),
            //    'type_name' => 'is_likes',
            //    'type_count' => GoodsCommentCollect::getGoodsCollectionNum($data['goods_id']),
            //],
        ];

        return ApiReturn::r(1, ['list' => $comment, 'total' => $total, 'tabList' => $tabList], lang('请求成功'));
    }

    /**
     * 直接购买获取创建订单的信息
     * @param array $data
     * @param array $user
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     * @created 2019/10/24 18:01
     */
    public function get_one_order_info($data = [], $user = [])
    {
        $userId = $user['id'];
        $send_type = $data['send_type'] ?? 0;
        if ($data['sku_id']) {
            //获取sku商品信息
            $goods = GoodsSku::alias('sku')->leftJoin('goods g', 'g.id=sku.goods_id')
                ->where('sku_id', $data['sku_id'])
                ->field('g.id,sku.sku_id,g.cid,g.discounts,g.name,g.freight_template_id,g.is_shipping,sku.shop_price,sku.member_price,sku.key_name,sku.market_price,g.thumb,sku.stock,g.is_sale,g.status,sku.status as skustatus,sku.sku_weight,g.amount_condition,g.is_integral')
                ->find();
            if (!$goods['skustatus']) {
                return ApiReturn::r(0, [], lang('商品无效，无法购买'));
            }
        } else {
            //获取单商品信息
            $goods = GoodsModel::where('id', $data['goods_id'])->field('id,cid,discounts,name,shop_price,member_price,market_price,thumb,stock,is_shipping,is_sale,status,freight_template_id,weight as sku_weight,amount_condition,is_integral')->find();
        }
        if (!$goods['is_sale']) {
            return ApiReturn::r(0, [], lang('商品下架，无法购买'));
        }
        if (!$goods['status']) {
            return ApiReturn::r(0, [], lang('商品无效，无法购买'));
        }
        if ($goods['stock'] < $data['number']) {
            return ApiReturn::r(0, [], lang('库存不足，无法购买'));
        }

        $goods['number'] = $data['number']; // 购买数量
        $goods['thumb'] = get_file_url($goods['thumb']); //商品缩略图
        $info['order_type'] = 3; //订单类型  
        $calculate_price = $goods['shop_price'];
        $goods['activity_id'] = 0;
        $freight = Freight::where("id", $goods['freight_template_id'])->field("name,freight_explain")->find();
        $goods['freight_explain'] = $freight['freight_explain'];
        $goods['freight_name'] = $freight['name'];
        $info['goods'][] = $goods;
        $orderGoodsMoney = bcmul($calculate_price, $data['number'], 2); //订单商品总价
        $goods_cid[] = [
            "cid" => $goods['cid'],
            "money" => $orderGoodsMoney
        ];
        $goods_iid[] = [
            "goods_id" => $goods['id'],
            "money" => $orderGoodsMoney
        ];
        //反馈参数返回优惠券查询参数
        $info['coupon_search']['moeny'] = $orderGoodsMoney;
        $info['coupon_search']['category'] = array_values($goods_cid);
        $info['coupon_search']['goods'] = array_values($goods_iid);

        //如果提交了优惠券id，则查询数据库中的优惠券
        $cou = new \app\operation\model\CouponRecord();
  
        if ($data['coupon_id']) {
            $coupon = $cou->get_user_coupon(['cr.user_id' => $user['id'], 'cr.id' => $data['coupon_id'], 'cr.status' => 1, 'oc.type' => 0]);
            if ($coupon) {
                $info['coupon'] = $coupon;
            }else{
                $info['coupon'] = null;
            }
        } else if (!$data['use_not_coupon']) {
            $coupon = $cou->get_best_coupon($user['id'], $orderGoodsMoney, $goods_cid, $goods_iid);
            $info['coupon'] = $coupon[0] ?? null;
        }
        //传递的订单收货地址
        if ($data['address_id']) {
            $address = AddressModel::getOneAddress($userId, $data['address_id']);
        } else {
            $address = [];
        }
        $info['address'] = $address;


        #------------------------运费计算
        $expressPrice = 0;

        //非自提计算运费
        if ($address && $send_type != 1) {
            $freight = new Freight();
            $cityId = $address['city_id']; //收货城市编号
            $freightTemplateId = $goods['freight_template_id']; //商品运费模板
            //判断运送范围
            if (!$freightTemplateId) {
                return ApiReturn::r(-1, [], "请稍后,该商品正在调配");
            }
            if (!$cityId) {
                return ApiReturn::r(-1, [], "很抱歉,您的收货地址不在配送范围内");
            }
            $res = $freight->checkAddress($cityId, $freightTemplateId);
            if ($res == false) {
                return ApiReturn::r(-1, [], "很抱歉,您的收货地址不在配送范围内");
            }
            //是否免运费              
            $condition = ($goods['is_shipping'] == 1) || ($goods['amount_condition'] > 0 && bccomp($goods['amount_condition'], $orderGoodsMoney, 2) < 1); //包邮或满足包邮条件
            // 不免运费、非自提 开始计算运费     
            if (!$condition) {
                $goodsWeight = $goods['sku_weight']; //商品重量
                $number = $data['number']; //下单数量      
                // 商品总重量（g）转（kg）
                $totalWeight = ceil(bcdiv(bcmul($goodsWeight, $number, 2), 1000, 2));
                // 计算配送费用
                $expressPrice = $freight->get($freightTemplateId, ['rule'])->calcTotalFee($number, $totalWeight, $cityId);
            }
        }
        #------------------------运费计算

        $info['express_price'] = $expressPrice;
        // halt($goods_price);
        // 商品总价
        $info['goods_price'] = $orderGoodsMoney;

        //加上运费后的价格
        $total_money = bcadd($orderGoodsMoney, $info['express_price'], 2);
        // 减去优惠券后的价格
        if( $info['coupon']){
            $info['payable_money'] = bcsub($total_money, $info['coupon']['money'], 2);
        }else{
            $info['payable_money'] = $total_money;
        }      

        //积分抵扣金额--暂时屏蔽
        $info['is_integral_reduce'] = 0;

        //获取用户默认的提货人信息 wangph 修改于 2021-4-21
        $info['pickup_default'] = UserPickupModel::getDefaultInfo($user['id']);

        return ApiReturn::r(1, $info, lang('请求成功'));
    }

    /**
     * 直接购买批发商品获取创建订单的信息
     * @param array $data
     * @param array $user
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     * @created 2019/10/24 18:01
     */
    public function get_wholesale_order_info($data = [], $user = [])
    {

        return ApiReturn::r(1, [], lang('接口废弃'));
    }

    /**
     * 购物车购买获取创建订单的信息
     * @param array $data .coin_id int 牛币券ID[选填]
     * @param array $data .cart_ids String 购物车ID 1,2,3,4,5[必填]
     * @param array $data .use_not_coupon int 不使用优惠券1;使用优惠券:0[选填]
     * @param array $data .coupon_id int 优惠券ID[选填]
     * @param array $user
     * @author 刘明美 [ liumingmei@zhongbenjituan.com ]
     * @created 2019/10/24 18:01
     */
    public function get_cart_order_info($data = [], $user = [])
    {
        $send_type = $data['send_type'] ?? 0;
        $cart_ids = explode(',', $data['cart_ids']);
        if (count($cart_ids) < 1) {
            return ApiReturn::r(0, [], lang('请选择要购买的商品'));
        }
        $map[] = ['user_id', '=', $user['id']];
        $map[] = ['id', 'in', $cart_ids];
        $cart = \app\goods\model\Cart::where($map)->select();
        if ($cart->count() != count($cart_ids)) {
            return ApiReturn::r(0, [], lang('所选购物车商品已失效，请刷新'));
        }
        //获取默认地址信息
        $where[] = ['user_id', '=', $user['id']];
        if ($data['address_id']) {
            $where[] = ['address_id', '=', $data['address_id']];
        } else {
            $where[] = ['is_default', '=', 1];
        }
        $address = AddressModel::get_one_address($where);
        $info['address'] = $address ? $address : [];

        $GoodsSku = new GoodsSku();
        //处理商品，过滤掉库存不足的，下架的，禁用的商品
        $money = 0;
        $express = 0;
        $express_arr = [];
        $freight = new \app\order\model\Freight();
        //list_fail保存不能购买的商品
        $list_fail = [];
        $jiage = $cateJiage = [];
        $all_jiage = 0;

        foreach ($cart as $v) {
            if ($v['sku_id'] != 0) {
                //获取sku商品信息
                $goods = $GoodsSku->alias('sku')->leftJoin('goods g', 'g.id=sku.goods_id')
                    ->where('sku_id', $v['sku_id'])
                    ->field('g.id,g.discounts,sku.sku_id,g.cid,g.name,g.amount_condition,sku.shop_price,sku.member_price,sku.key_name,sku.market_price,sku.sku_weight,g.thumb,sku.stock,g.is_shipping,g.freight_template_id,g.is_sale,g.status,sku.status as skustatus,g.is_wholesale')
                    ->find();
                if (!$goods['skustatus']) {
                    //无效的sku
                    $goods['thumb'] = get_file_url($goods['thumb']);
                    $goods['reason'] = lang('无效的sku');
                    $list_fail[] = $goods;
                    continue;
                }
            } else {
                //获取单商品信息
                $goods = GoodsModel::where('id', $v['goods_id'])->field('id,cid,discounts,name,shop_price,member_price,market_price,thumb,stock,is_shipping,freight_template_id,is_sale,status,weight,amount_condition,is_wholesale')->find();
            }

            $goods['number'] = $v['num'];
            $goods['thumb'] = get_file_url($goods['thumb']);
            if (!$goods['is_sale']) {
                //下架的商品
                $goods['reason'] = lang('下架的商品');
                $list_fail[] = $goods;
                continue;
            }
            if (!$goods['status']) {
                $goods['reason'] = lang('禁用的商品');
                $list_fail[] = $goods;
                //禁用的商品
                continue;
            }
            if ($goods['stock'] < $v['num']) {
                $goods['reason'] = lang('库存不足的商品');
                $list_fail[] = $goods;
                //库存不足的商品
                continue;
            }
            //会员价暂时屏蔽 
            $calculate_price = $goods['shop_price'];
            //商品总价        
            $goods_money = bcmul($v['num'], $calculate_price, 2);
            //是否免运费   
            //下面，这个运费的算法是错误的，极端错误的， 为什么呢，amount_condition 没有考虑到同一个商品多个SKU的情况，革命不彻底
            //首先根据商品ID统计价格
            //$condition = ( $goods['is_shipping'] == 1 ) || ( $goods['amount_condition'] > 0 && bccomp($goods['amount_condition'], $goods_money,2) < 1 );//包邮或满足包邮条件
            //这里仅检查运费
            //仅检查配送区域.原有包邮条件不正确，去掉
            if ($address && $send_type != 1) {
                if (!$address['city_id']) {
                    $goods['reason'] = lang('收货地址不在配送范围');
                    $list_fail[] = $goods;
                    continue;
                }
                if (!$goods['freight_template_id']) {
                    $goods['reason'] = lang('该商品正在调配');
                    $list_fail[] = $goods;
                    continue;
                }
                $res = $freight->checkAddress($address['city_id'], $goods['freight_template_id']);
                if (!$res) {
                    $goods['reason'] = lang('收货地址不在配送范围');
                    $list_fail[] = $goods;
                    continue;
                }
                //不包邮累计运费
                if ($goods['is_shipping'] != 1) {
                    // 商品总重量
                    if ($v['sku_id'] != 0) {
                        $goods_total_weight = bcmul($goods['sku_weight'], $v['num'], 2);
                    } else {
                        $goods_total_weight = bcmul($goods['weight'], $v['num'], 2);
                    }
                    //统计每个商品的运费模板
                    $express_arr[$goods["id"]] = [
                        'freight_template_id' => $goods['freight_template_id'],
                        'weight' => bcadd($express_arr[$goods["id"]]['weight'] ?? 0, $goods_total_weight, 2),
                        'num' => bcadd($express_arr[$goods["id"]]['num'] ?? 0, $v['num'], 0),
                        'goods_money' => bcadd($express_arr[$goods["id"]]['goods_money'] ?? 0, $goods_money, 2), //根据商品统计满包邮金额
                        'amount_condition' => $goods['amount_condition'], //每个商品的满包邮是不累加的
                    ];
                }
            }
            //震惊，震惊，这个静态查询的赋值覆盖了 $freight,因此改成$freights ，并使用数组来提高性能
            if (!isset($freights[$goods['freight_template_id']])) {
                $freights[$goods['freight_template_id']] = $freight->where("id", $goods['freight_template_id'])->field("name,freight_explain")->find();
            }
            $goods['freight_explain'] = $freights[$goods['freight_template_id']]['freight_explain'];
            $goods['freight_name'] = $freights[$goods['freight_template_id']]['name'];

            $goodslist[] = $goods;

            //此处统优惠券计价格有误2021年10月20日21:20:41 改。
            $jiage[$v['goods_id']]['goods_id'] = $v['goods_id'];
            $jiage[$v['goods_id']]['money'] = bcadd($jiage[$v['goods_id']]['money'] ?? 0, $goods_money, 2);

            $cateJiage[$v['id']]['cid'] = $goods['cid'];

            $cateJiage[$v['id']]['money'] = bcadd($cateJiage[$v['id']]['money'] ?? 0, $goods_money, 2);

            $all_jiage = $money = bcadd($all_jiage, $goods_money, 2);
        }

        //运费计算
        $express_arr_sum = [];
        foreach ($express_arr as $val) {
            //若满足满包邮条件，则跳过不计,革命要彻底
            $condition = $val['amount_condition'] > 0 && bccomp($val['amount_condition'], $val['goods_money'], 2) < 1;
            if ($condition) {
                continue;
            }
            //下面是按照运费模板ID来重新统计重量和数量.这个统计是由问题的，我重新捋了下
            //这里不转KG，会有精度问题，下面再转
            $express_arr_sum[$val['freight_template_id']]['weight'] = bcadd($express_arr_sum[$val['freight_template_id']]['weight'] ?? 0, $val["weight"], 2);
            $express_arr_sum[$val['freight_template_id']]['num'] = bcadd($express_arr_sum[$val['freight_template_id']]['num'] ?? 0, $val["num"], 0);
        }
        //汇算运费
        foreach ($express_arr_sum as $k => $v) {
            //$res = $freight->checkAddress($address['city_id'], $k);//这里上面已验证，此处不重新验证了  
            // 商品总重量（g）转（kg）
            $totalWeight = ceil(bcdiv($v['weight'], 1000, 2));
            $express_price = $freight->get($k, ['rule'])->calcTotalFee($v['num'], $totalWeight, $address['city_id'], $k);
            $express = bcadd($express, $express_price, 2);
        }

        $info['tip'] = 0;
        $info['msg'] = '';
        $info['order_money'] = $money;
        $info['goods'] = $goodslist ? $goodslist : [];

        // 可用优惠券
        $cou = new \app\operation\model\CouponRecord();
        $coupon = [];
        if (!$data['use_not_coupon']) {
            if ($data['coupon_id']) {
                $coupon = $cou->get_user_coupon(['cr.user_id' => $user['id'], 'cr.id' => $data['coupon_id'], 'cr.status' => 1, 'oc.type' => 0]);
                $coupon = $coupon ? [$coupon] : null;
            } else {
                //$coupon = $cou->get_best_coupon_new($user['id'], $all_jiage, $cateJiage,$jiage);
                $coupon = [];
            }
        }

        $info['coupon'] = $coupon[0] ?? null;
        $info['express_price'] = $express;

        $payable_money = bcadd($money, $express, 2);

        // 计算应付金额  
        $info['order_type'] = 3;

        $info['payable_money'] = $info['coupon'] ? bcsub($payable_money, $info['coupon']['money'], 2) : $payable_money;

        //获取用户默认的提货人信息 wangph 修改于 2021-4-21
        $info['pickup_default'] = UserPickupModel::getDefaultInfo($user['id']);
        $info['list_fail'] = $list_fail;

        //反馈参数返回优惠券查询参数
        $info['coupon_search']['moeny'] = $all_jiage;
        $info['coupon_search']['category'] = array_values($cateJiage);
        $info['coupon_search']['goods'] = array_values($jiage);

        return ApiReturn::r(1, $info, lang('请求成功'));
    }

    /**
     * 商品分享链接生成-H5+二维码
     * @param array $data
     * @param array $user
     * @author jxy [ 415782189@qq.com ]
     * @created 2020/3/24 16:01
     */
    public function share($data = [], $user = [])
    {
        $map[] = ['goods_id', '=', $data['goods_id']];
        $map[] = ['activity_id', '=', $data['activity_id']];
        $map[] = ['sku_id', '=', $data['sku_id']];
        $map[] = ['uid', '=', $user['id']];
        //安卓下载地址
        $is_update_apk = Db::name("admin_version_log")->where(["vid" => 1, "type" => 2, "status" => 1])->order("create_time DESC")->value("url");
        $is_update_apk = urlencode($is_update_apk);

        $html = "/h5/index.html";

        $domain = config('web_site_domain');

        $shareGoods = Db::name('goods_share')->where($map)->find();
        if ($shareGoods) {
            $end_url = 'goods_id=' . $data['goods_id'] . '&activity_id=' . $data['activity_id'] . '&sku_id=' . $data['sku_id'] . '&user_id=' . $user['id'] . '&apk_download_url=' . $is_update_apk . '&share_sign=' . $shareGoods['share_sign'];
            $url = $html . '#/?' . $end_url;

            $info = [
                'url' => $domain . $url,
                'qrcode_url' => $domain . $shareGoods['qrcode_url']
            ];
            return ApiReturn::r(1, $info, lang('请求成功'));
        }
        Db::startTrans();
        try {
            $parms['goods_id'] = $data['goods_id'];
            $parms['activity_id'] = $data['activity_id'];
            $parms['uid'] = $user['id'];
            $parms['sku_id'] = $data['sku_id'];
            $parms['share_sign'] = \service\Str::randString(10, 0);

            $end_url = 'goods_id=' . $data['goods_id'] . '&activity_id=' . $data['activity_id'] . '&sku_id=' . $data['sku_id'] . '&user_id=' . $user['id'] . '&apk_download_url=' . $is_update_apk . '&share_sign=' . $parms['share_sign'];
            $url = $html . '#/?' . $end_url;

            $info["url"] = $domain . $url;

            //生成二维码
            $code_url = addons_action('Qrcode/Qrcode/generate', [$info['url']]);

            if (!$code_url) {
                throw new \Exception(lang('生成分享二维码失败'));
            }
            $info['qrcode_url'] = $domain . $code_url;
            $parms['qrcode_url'] = $code_url;
            $parms['create_time'] = time();
            $res = Db::name('goods_share')->insertGetId($parms);
            if (!$res) {
                throw new \Exception(lang('生成分享识别码失败'));
            }
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            return ApiReturn::r(0, '', $e->getMessage());
        }
        TaskModel::doTask($user['id'], 'shareGoods');
        return ApiReturn::r(1, $info, lang('请求成功'));
    }

    /**
     * 小程序商品分享链接
     * @param array $data
     * @param array $user
     * @author zhougs
     * @created 2020年12月15日10:58:34
     */
    public function goods_share($data = [], $user = [])
    {

    }

    /**
     * 获取临时二维码
     * @param $requests .scene string 场景
     * @param $requests .page url 已经发布的小程序存在的页面路径
     * @param $requests .with int 二维码宽度
     * @return \think\response\Json
     * @since 2020年8月1日17:57:40
     * @author zenghu<1427305236@qq.com>
     */
    public function getMiniQrcode($requests = [], $user = [])
    {
        $width = empty($requests['width']) ? 430 : $requests['width'];

        try {
            $result = addons_action('WeChat', 'AuthCode', 'get_qrcode_limit', [$requests['scene'], $requests['page'], $width]);
            return ApiReturn::r(1, [
                // 请勿修改文件头长度 避免客户端出错
                "base64" => "data:image/png;base64," . $result
            ], lang('请求成功'));
        } catch (\Exception $e) {
            return ApiReturn::r(0, [], $e->getMessage());
        }
    }

    /**
     * 商品跑马灯
     * @param $data
     * @param $user
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhougs
     */
    public function getUserBuyGoods($data, $user)
    {
        // 检测参数值
        if (empty($data['goods_id'])) {
            return ApiReturn::r(0, [], lang('参数不能为空'));
        }
        $userData = [];
        $where[] = ["ogl.goods_id", "=", $data['goods_id']];
        $where[] = ["o.status", "gt", 0];
        $where[] = ["o.pay_status", "=", 1];

        $orderUser = \app\common\model\Order::alias("o")
            ->join("order_goods_list ogl", 'o.order_sn = ogl.order_sn', 'left')
            ->field('user_id')
            ->where($where)
            ->orderRaw("RAND()")
            ->find();
        if ($orderUser) {
            $userData = Db::name("user")->field("id,user_nickname,head_img")->where("id", $orderUser['user_id'])->find();
            if ($userData) {
                $userData['head_img'] = get_file_url($userData['head_img']);
            }
        }
        return ApiReturn::r(1, $userData, lang('获取成功'));
    }

    /**
     * 热销榜单
     * @param $data
     * @param $user
     * @return \think\response\Json
     * @author zhougs
     */
    public function GoodsSaleNumTop($data, $user)
    {
        if (!$data['cid']) {
            return ApiReturn::r(0, [], lang('参数错误'));
        }
        $resData = [];
        $resData['list'] = $this->GoodsSaleNum($data['cid']);
        if (count($resData) > 0) {
            $topName = Db::name("goods_hot_top")->where(["status" => 1, "category_id" => $data['cid']])->value("name");
            $resData['top_name'] = $topName;
        }
        return ApiReturn::r(1, $resData, lang('请求成功'));
    }

    //获取商品销售情况
    public function GoodsSaleNum($cid)
    {
        if (!$cid) {
            return [];
        }
        $goods = GoodsModel::where("cid", $cid)->order("sales_sum DESC")->limit(10)->select();
        $resData = [];
        if (count($goods) > 0) {
            $eTime = time();
            $sTime = $eTime - 86400 * 7;
            foreach ($goods as $key => $val) {
                $where = [];
                $resData[$key]['id'] = $val['id'];
                $resData[$key]['name'] = $val['name'];
                $resData[$key]['thumb'] = get_file_url($val['thumb']);
                $resData[$key]['shop_price'] = $val['shop_price'];
                $where[] = ["o.create_time", "between", [$sTime, $eTime]];
                $where[] = ["ogl.goods_id", "=", $val['id']];
                $where[] = ["o.status", "gt", 0];
                //七天内购买件数
                $sevenDaysSale = Db::name("order")
                    ->alias("o")
                    ->join("order_goods_list ogl", "o.order_sn = ogl.order_sn", "left")
                    ->where($where)
                    ->sum("ogl.num") ?: 0;
                $resData[$key]['seven_days_sale'] = $sevenDaysSale;

                //累计会员购买量
                $userBuyNum = Db::name("order")
                    ->alias("o")
                    ->join("order_goods_list ogl", "o.order_sn = ogl.order_sn", "left")
                    ->where([["ogl.goods_id", "=", $val['id']], ["o.status", "gt", 0]])
                    ->count("o.user_id") ?: 0;
                $resData[$key]['user_buy_num'] = $userBuyNum;
            }
        }
        return $resData;
    }

    //获取商品销售排行
    public function getGoodsSalesRanking($goods_id, $cid)
    {
        $goods = GoodsModel::where("cid", $cid)->order("sales_sum DESC")->column("id");
        if (count($goods) > 0) {
            $array = array_flip($goods);
            return $array[$goods_id] + 1;
        }
        return 0;
    }


    /**
     * 高级搜索栏获取多条件商品条数
     * @author 曾虎 [ 1427305236@qq.com ]
     * @since 2020年12月22日14:11:01
     */
    public function getGoodsCount($requests = [])
    {
        // 模拟参数
        // $requests = array(
        //     'keyword' => lang('白酒'), // 搜索关键字
        //     'service_lable_id' => '1,2,3,4', // 服务标签ID
        //     'min_price' => '100', // 最小金额
        //     'max_price' => '500', // 最大金额
        //     'brand_id' => '2,3,4', // 品牌ID
        //     'goods_cid' => '3', // 分类ID 
        //     'sku_id' => '68,74,75,76,67,62,34,50', // 分类ID
        // );
        // 处理搜索条件
        $where = [];
        // 搜索关键字
        if ($requests['keyword']) {
            $where[] = \app\goods\model\Goods::getKeywordWhereMap($requests['keyword'], 'g.name');
        }
        // 服务标签ID
        if ($requests['service_lable_id']) {
            $labelWhere = \app\goods\model\Goods::getFinInsetAll($requests['service_lable_id'], 'g.goods_label_service');
            if ($labelWhere) {
                $where[] = $labelWhere;
            }
        }
        // 商品价格区间搜索
        if (!empty($requests['min_price']) && $requests['min_price'] > 0) {
            $where[] = ['g.shop_price', ">", $requests['min_price']];
        }
        if (!empty($requests['max_price']) && $requests['max_price'] > 0) {
            $where[] = ['g.shop_price', "<=", $requests['max_price']];
        }
        // 品牌ID
        if ($requests['brand_id']) {
            $arr = array_filter(array_unique(explode(',', $requests['brand_id'])));
            if ($arr) {
                $where[] = ['g.brand_id', "in", $arr];
            }
        }

        if ($requests['goods_cid']) {
            $category_ids = self::getAllCodeTypeByCid($requests['goods_cid']);
            $where[] = ['g.cid', "in", $category_ids];
        }
        // SKU检索商品
        if ($requests['sku_id']) {
            $skuWhere = \app\goods\model\Goods::getFinInsetAll($requests['sku_id'], "REPLACE(`key`,'_',',')");
            if ($skuWhere) {
                $where[] = ["g.id", "in", function ($query) use ($skuWhere) {
                    $query->name("goods_sku")->where($skuWhere)->field("goods_id");
                }];
            }
        }
        // 根据条件获取商品条数
        $count = GoodsModel::alias('g')->where($where)->count();
        return ApiReturn::r(1, $count, lang('获取成功'));
    }

    /**
     * 根据商品分类获取分类下支持的SKU列表
     * @author 曾虎 [ 1427305236@qq.com ]
     * @since 2020年12月23日10:11:31
     */
    public function getGoodsSkuList($requests = [])
    {
        // 模拟参数
        // $requests = array(
        //     'goods_cid' => '202', // 分类ID 
        // );
        // 查询分类下的规格信息
        $skuTypeList = Type::alias('t')
            ->field('gts.id,gts.name')
            ->where(['t.cid' => $requests['goods_cid'], 't.status' => 1, 'gts.status' => 1])
            ->join('goods_type_spec gts', 'gts.typeid = t.id', 'LEFT')
            ->select();
        // 处理sku数据
        $goodsSkuList = [];
        foreach ($skuTypeList as $val) {
            $goodsSkuList[$val['name']] = GoodsTypeSpecItem::field('id,item')->where(['specid' => $val['id']])->select();
        }

        return ApiReturn::r(1, $goodsSkuList, lang('获取成功'));
    }

    /**
     * 商品评论回复
     * @param $data
     * @param $user
     * @return \think\response\Json
     * @author zhougs
     * @since 2021年1月6日14:25:34
     */
    public function goodsCommentReply($data, $user)
    {
        if (empty($data)) {
            return ApiReturn::r(0, [], lang('参数错误'));
        }
        $goodsComment = GoodsComment::get($data['gc_id']);
        if (!$goodsComment) {
            return ApiReturn::r(0, [], lang('没有此评论'));
        }
        $head_img = User::where("id", $user['user_id'])->value("head_img");
        $insData = [
            "user_id" => $user['user_id'],
            "user_nickname" => $user['user_nickname'],
            "head_img" => $head_img,
            "content" => $data['content'],
            "gc_id" => $data['gc_id'],
            "create_time" => time(),
        ];
        $res = Db::name("goods_comment_reply")->insertGetId($insData);
        if (!$res) {
            return ApiReturn::r(0, [], lang('回复失败'));
        }
        return ApiReturn::r(1, [], lang('回复成功'));
    }

    /**
     * 获取商品评论详情
     * @param $data
     * @param $user
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhougs
     * @since 2021年1月6日16:54:46
     */
    public function getGoodsCommentDetail($data, $user)
    {
        if (empty($data)) {
            return ApiReturn::r(0, [], lang('参数错误'));
        }
        $retData = [];
        $goods_comment = [];
        $goods_comment_reply_list = [];
        $comment = Db::name("goods_comment")->alias('c')
            ->join('user u', 'c.user_id = u.id')
            ->field('c.id,c.type,c.thumb,c.video,c.create_time,c.content,c.star,u.head_img,u.user_nickname,c.sku_id')
            ->where(["c.id" => $data['gc_id'], 'c.status' => 1])
            ->select();
        if (count($comment) > 0) {
            foreach ($comment as $key => $value) {
                if ($value['type'] == 1) {
                    $comment[$key]['user_nickname'] = lang('匿名用户');
                    $comment[$key]['head_img'] = config('web_site_domain') . '/static/admin/images/user_none.png';
                } else {
                    $comment[$key]['user_nickname'] = str2sub($value['user_nickname'], 1, '***');
                    $comment[$key]['head_img'] = get_file_url($value['head_img']);
                }
                $comment[$key]['thumb'] = get_files_url($value['thumb']);
                $comment[$key]['video'] = get_files_url($value['video']);
                $comment[$key]['create_time'] = date('Y-m-d', $value['create_time']);
                if ($value['sku_id']) {
                    $comment[$key]['key_name'] = GoodsSku::where('sku_id', $value['sku_id'])->value('key_name');
                }
                $comment[$key]['is_likes'] = GoodsCommentCollect::isCollection($user['user_id'], $value['id']) ?? 0;
                $comment[$key]['likes_num'] = GoodsCommentCollect::collectionNum($value['id']) ?? 0;
            }
            $goods_comment = $comment[0];
        }
        $retData['goods_comment_detail'] = $goods_comment;
        $goods_comment_reply = Db::name("goods_comment_reply")
            ->where(["gc_id" => $data['gc_id']])
            ->paginate()
            ->each(function ($item) {
                if ($item['is_merchant'] == 1) {
                    $item['user_nickname'] = lang('商家回复');
                } else {
                    $item['user_nickname'] = str2sub($item['user_nickname'], 1, '***');
                }

                $item['head_img'] = get_file_url($item['head_img']);
                $item['create_time'] = date("Y-m-d H:i:s", $item['create_time']);
                return $item;
            });
        if (count($goods_comment_reply) > 0) {
            $goods_comment_reply_list = $goods_comment_reply;
        }
        $retData['goods_comment_reply_list'] = $goods_comment_reply_list;
        return ApiReturn::r(1, $retData, lang('获取成功'));
    }

    /**
     * 评论点赞
     * @param array $data
     * @param array $user
     * @author zhougs
     * @created 2021年1月9日10:21:46
     */
    public function set_goods_comment_collection($data = [], $user = [])
    {
        $res = GoodsCommentCollect::isCollection($user['id'], $data['collect_id']);
        if ($res) {
            // 取消点赞/关注
            $ret = GoodsCommentCollect::delCollection($user['id'], $data['collect_id']);
            if ($ret) {
                return ApiReturn::r(1, ['is_collection' => 0], lang('已取消'));
            }
        } else {
            $data['user_id'] = $user['id'];
            $data['create_time'] = time();
            $ret = GoodsCommentCollect::create($data);
            if ($ret) {
                return ApiReturn::r(1, ['is_collection' => 1], lang('成功'));
            }
        }
        return ApiReturn::r(0, [], lang('操作失败'));
    }

}
